package org.lee.pdf.util;

import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.fit.pdfdom.PDFDomTree;
import org.lee.util.FileUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;

/**
 * @author jackielee
 * @version 1.0
 * @description Pdf2HtmlUtil
 * @date 2021/6/2
 */
public class Pdf2HtmlUtil {

  public static void pdf2Html(String pdfFileName, String outputPath) {
    File pdf = new File(pdfFileName);
    try (PDDocument doc = Loader.loadPDF(pdf)) {
      FileOutputStream out =
          new FileOutputStream(
              String.format("%s%s%s.html", outputPath, File.separator, FileUtils.getFileName(pdf)));
      OutputStreamWriter writer = new OutputStreamWriter(out);
      PDFDomTree tree = new PDFDomTree();
      tree.writeText(doc, writer);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static BufferedImage pdf2Png(InputStream pdfStream) {
    try (PDDocument doc = Loader.loadPDF(pdfStream)) {
      PDFRenderer renderer = new PDFRenderer(doc);
      int pageCount = doc.getNumberOfPages();
      BufferedImage img = null;
      for (int i = 0; i < pageCount; ++i) {
        if (img != null) {
          img = combineBufferedImage(img, renderer.renderImageWithDPI(i, 144));
        }
        if (i == 0) {
          img = renderer.renderImageWithDPI(i, 144); // windows native dpi
        }
      }
      return combineBufferedImage(img);
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }

  public static void pdf2Png(String pdfFileName, String savePath) {
    File pdf = new File(pdfFileName);
    try (PDDocument doc = Loader.loadPDF(pdf)) {
      PDFRenderer renderer = new PDFRenderer(doc);
      int pageCount = doc.getNumberOfPages();
      BufferedImage img = null;
      for (int i = 0; i < pageCount; ++i) {
        ImageIO.write(
            renderer.renderImageWithDPI(i, 144),
            "png",
            new File(
                String.format(
                    "%s%s%s%d.png", savePath, File.separator, FileUtils.getFileName(pdf), i)));
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static String base642Html(String base64) {
    StringBuffer sb = new StringBuffer(1024);
    sb.append("<html><head>");
    sb.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
    sb.append("<title>pdf2html</title>");
    sb.append("<style>");
    sb.append("body{\r\ntext-align:center;\r\nbackground-color:#C1C1C1;\r\n}");
    sb.append("</style>");
    sb.append("</head>");
    sb.append("<body>");
    sb.append("<img src=\"data:image/png;base64," + base64 + "\"/>");
    sb.append("</body>");
    return sb.toString();
  }

  public static String img2Base64(BufferedImage img) {
    try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
      ImageIO.write(img, "png", out);
      byte[] buffer = out.toByteArray();
      return Base64.getEncoder()
          .encodeToString(buffer)
          .trim()
          .replaceAll("\n", "")
          .replaceAll("\r", "");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }

  private static BufferedImage combineBufferedImage(BufferedImage... images) {
    int width = 0, height = 0;
    for (BufferedImage img : images) {
      if (width < img.getWidth()) {
        width = img.getWidth();
      }
      height += img.getHeight();
    }
    BufferedImage combineImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = combineImg.createGraphics();
    int x = 0, y = 0;

    g.setStroke(new BasicStroke(2.0f));
    g.setColor(new Color(193, 193, 193));
    for (BufferedImage img : images) {
      g.drawLine(x, y, width, y);
      g.drawImage(img, x, y, null);
      y += img.getHeight();
    }
    return combineImg;
  }
}
